package com.df.tools.handler.impl;

import com.df.tools.config.ConfigProperties;
import com.df.tools.handler.IHandler;
import com.df.tools.msg.MsgDefinition;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 前端代码处理器
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class FrontHandler implements IHandler {

    private final ConfigProperties configProperties;
    @Override
    public boolean canHandle() {
        return true;
    }

    @Override
    public void handle(List<MsgDefinition> msgDefinitions) throws Exception {
        System.out.println("================生成前端代码===================");
        List<MsgDefinition> frontMsgDefinitions = msgDefinitions.stream().filter(m -> m.getType().equals(configProperties.getFront().getMsgType())).collect(Collectors.toList());
        List<String> packages = frontMsgDefinitions.stream().map(def -> def.getPackage_name()).distinct().collect(Collectors.toList());

        Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
        // Specify the source where the template files come from. Here I set a
        // plain directory for it, but non-file-system sources are possible too:
        String path = Thread.currentThread().getContextClassLoader().getResource("templates/front").getPath();
        cfg.setDirectoryForTemplateLoading(new File(path));
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

        Map<String, Object> root = new HashMap<>();
        root.put("msgDefinitions", msgDefinitions);
        root.put("packages", packages);
        //生成消息管理器
        generatorMsgManager(cfg, root,frontMsgDefinitions);
        //生成服务器到客户端的消息处理脚本
        generatorMsgScript(cfg,root,frontMsgDefinitions);
        //生成消息处理脚本管理器
        generatorMsgScriptManager(cfg,root,frontMsgDefinitions);
    }

    private void generatorMsgScriptManager(Configuration cfg, Map<String, Object> root, List<MsgDefinition> frontMsgDefinitions) throws Exception {
        root.put("frontMsgDefinitions",frontMsgDefinitions);
        Template temp = cfg.getTemplate("MsgScriptManager.ftl");

        String scriptPath = configProperties.getFront().getMsgScriptPath();
        if (!scriptPath.endsWith("\\") && !scriptPath.endsWith("/")) {
            scriptPath = scriptPath + File.separator;
        }

        String nowFilePath = scriptPath +  File.separator  + "MsgScriptManager.ts";
        Writer writer = new FileWriter(nowFilePath);
//        Writer writer = new OutputStreamWriter(System.out);
        temp.process(root, writer);
        log.info("MsgScriptManager.ts 生成成功！:" + configProperties.getFront().getMsgManagerPath());
    }

    private void generatorMsgScript(Configuration cfg, Map<String, Object> root, List<MsgDefinition> frontMsgDefinitions) throws Exception{
        String scriptPath = configProperties.getFront().getMsgScriptPath();
        if (!scriptPath.endsWith("\\") && !scriptPath.endsWith("/")) {
            scriptPath = scriptPath + File.separator;
        }
        Template temp = cfg.getTemplate("S2C_SyncPositionScript.ftl");
        for (MsgDefinition frontMsgDefinition : frontMsgDefinitions) {
            String nowFilePath = scriptPath + frontMsgDefinition.getPackage_name() + File.separator + frontMsgDefinition.getName() + "Script.ts";
            //先检查文件是否存在，存在则跳过，防止把写过的代码给冲掉了
            root.put("nowMsgDefinition", frontMsgDefinition);
            File file = new File(nowFilePath);
            if (!file.exists()) {
                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {
                    parentFile.mkdir();
                }
                file.createNewFile();
              FileWriter writer = new FileWriter(file);
//                Writer writer = new OutputStreamWriter(System.out);
                temp.process(root, writer);
                log.info(frontMsgDefinition.getName() + "Script.ts 生成成功！:" + nowFilePath);
                continue;
            }
//            log.warn(bakendMsgDefinition.getName()+"Script.java 已经存在！:"+nowFilePath);
//            break;
        }

    }

    private void generatorMsgManager(Configuration cfg, Map<String, Object> root, List<MsgDefinition> frontMsgDefinitions) throws Exception{

        Template temp = cfg.getTemplate("MsgManager.ftl");
        Writer writer = new FileWriter(configProperties.getFront().getMsgManagerPath());
//        Writer writer = new OutputStreamWriter(System.out);
        temp.process(root, writer);
        log.info("前端MsgManager.ts 生成成功！:" + configProperties.getFront().getMsgManagerPath());
    }
}
